/*************************************************
 * 描述: 
 *
 * File: globaldelegaterouter.cpp
 * Author: shizhixin@mozihealthcare.cn
 * Date: 2025-10-21
 * Update: 
 * ************************************************/
#include "globaldelegaterouter.h"

#include <QAbstractProxyModel>
#include <private/table/delegate/columndelegaterouter.h>

GlobalDelegateRouter::GlobalDelegateRouter(QObject* parent)
	: QStyledItemDelegate(parent)
	  , m_defaultRouter(nullptr)
{
}

void GlobalDelegateRouter::setDefaultDelegate(QStyledItemDelegate* delegate)
{
	m_defaultRouter = delegate;
}

void GlobalDelegateRouter::setColumnRouter(int column, ColumnDelegateRouter* router)
{
	m_columnRouters[column] = router;
}

ColumnDelegateRouter* GlobalDelegateRouter::columnRouter(int column) const
{
	auto it = m_columnRouters.find(column);
	return it != m_columnRouters.end() ? it.value() : nullptr;
}

void GlobalDelegateRouter::setCellDelegate(int row, int column, QStyledItemDelegate* delegate)
{
	ColumnDelegateRouter* router = columnRouter(column);
	if (!router)
	{
		router = new ColumnDelegateRouter(this);
		setColumnRouter(column, router);
	}
	router->setCellDelegate(row, delegate);
}

QStyledItemDelegate* GlobalDelegateRouter::cellDelegate(int row, int column) const
{
	if (auto router = columnRouter(column))
	{
		return router->cellDelegate(row);
	}
	return nullptr;
}

QWidget* GlobalDelegateRouter::createEditor(QWidget* parent, const QStyleOptionViewItem& option,
                                            const QModelIndex& index) const
{
	if (auto d = delegateForIndex(index)) return d->createEditor(parent, option, index);
	return QStyledItemDelegate::createEditor(parent, option, index);
}

void GlobalDelegateRouter::setEditorData(QWidget* editor, const QModelIndex& index) const
{
	if (auto d = delegateForIndex(index)) return d->setEditorData(editor, index);
	QStyledItemDelegate::setEditorData(editor, index);
}

void GlobalDelegateRouter::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
	if (auto d = delegateForIndex(index)) return d->setModelData(editor, model, index);
	QStyledItemDelegate::setModelData(editor, model, index);
}

void GlobalDelegateRouter::paint(QPainter* painter, const QStyleOptionViewItem& option,
                                 const QModelIndex& index) const
{
	if (auto d = delegateForIndex(index)) return d->paint(painter, option, index);
	QStyledItemDelegate::paint(painter, option, index);
}

QStyledItemDelegate* GlobalDelegateRouter::delegateForIndex(const QModelIndex& index) const
{
	if (!index.isValid())
	{
		return m_defaultRouter;
	}
	QModelIndex sourceIndex = mapToSourceRecursive(index);
	if (auto router = columnRouter(sourceIndex.column())) return router->delegateForIndex(sourceIndex);
	return m_defaultRouter;
}

QModelIndex GlobalDelegateRouter::mapToSourceRecursive(const QModelIndex& index)
{
	QModelIndex current = index;
	const QAbstractItemModel* model = index.model();

	while (const QAbstractProxyModel* proxy = qobject_cast<const QAbstractProxyModel*>(model))
	{
		current = proxy->mapToSource(current);
		model = proxy->sourceModel();
	}
	return current;
}